using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;

namespace Charisma.Conventions
{
    public class PublicRepositoryConvention : IRepositoryConvention
    {
        #region IRepositoryConvention Members

        public IEnumerable<PropertyInfo> Find(Type type)
        {
            return type
                .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                .Where(HasValidType);
        }

        #endregion

        public static bool HasValidType(PropertyInfo property)
        {
            Contract.Requires(property != null);

            // Check whether property is at least IRepository descendant
            if (!Wellknown.Types.NonGenericRepository.IsAssignableFrom(property.PropertyType))
                return false;

            // Trying to find out the generic implementor type, i.e. IRepository<T>
            Type genericImplementorType = ReflectionService.GetGenericImplementorType(property.PropertyType);

            // It seems that property is of IRepository type but not IRepository<T>, so typeof(T) can't be discovered.
            if (genericImplementorType == null)
                return false;

            return true;
        }
    }
}